#include "../logs/bitLog.hpp"

/*
    1.第一个参数    logname     是日志器的名称
    2.第二个参数    thr_count   是要创建的线程数量
    3.第三个参数    msg_count   是要写入的消息条数
    4.第四个参数    msg_len     是单个消息的长度（Byte为单位），包含一个"\n"
*/
void bench(const std::string logname, size_t thr_count, size_t msg_count, size_t msg_len)
{
    // 1.获取日志器：
    bit::Logger::ptr logger = bit::getLogger(logname);
    if (logger.get() == nullptr)
    {
        std::cout << "没有这个日志器" << std::endl;
        return;
    }

    std::cout << "测试日志：" << msg_count << "条日志，总大小：" << (msg_count * msg_len / 1024 / 1024.0) << "MB" << std::endl;
    // 2.组织指定长度的日志信息：
    std::string msg(msg_len - 1, 'A'); // 空出一个字符放'\0'
    msg.push_back('\n');

    // 3.创建指定数量的线程：
    std::vector<std::thread> threads(thr_count);
    // 用于记录最高耗时的变量：
    size_t thr_msgc = msg_count / thr_count;
    double maxTime = -1;
    for (int i = 0; i < threads.size(); i++)
    {
        if ((i == threads.size() - 1) && (msg_count % thr_count))
            thr_count++;
        threads[i] = std::thread([&, i]() mutable
                                 {
                                     // 4.线程内部开始计时：
                                     auto start = std::chrono::high_resolution_clock::now();
                                     // 5.循环写日志：
                                     for(int j= 0; j < thr_msgc; j++)
                                     {
                                        logger->fatal("%s", msg.c_str());
                                     }
                                     // 6.线程内部计时结束：
                                     auto end = std::chrono::high_resolution_clock::now();
                                     std::chrono::duration<double> cost = end-start;
                                     maxTime = cost.count() > maxTime ? cost.count() : maxTime; 
                                     std::cout << "\tthread-" << i << "，\t输出" << thr_msgc << "条日志。\t耗时->" << cost.count() << "s\n"; });
    }
    for (int i = 0; i < thr_count; i++)
    {
        threads[i].join();
    }

    // 7.计算总的耗时（多线程是并发执行的，所以取耗时最高的线程的时间即可）：
    std::cout << "\t总耗时：" << maxTime << "s" << std::endl;

    // 进行输出打印：
    // 每秒钟打印的数据条数：
    size_t msg_presed = msg_count / maxTime;
    // 每秒钟打印的数据量（以MB为单位）：
    double size_presed = (msg_count * msg_len / maxTime) / 1024 / 1024;

    std::cout << "\t每秒中输出日志数量" << msg_presed << "条" << std::endl;
    std::cout << "\t每秒中输出日志大小" << size_presed << "MB" << std::endl;
}
void sync_log()
{
    bit::GlobalLogBuilder builder("sync");
    builder.buildLogFormat("%m");
    builder.buildSink<bit::FileSink>("sync.log");
    builder.build();
    bench("sync", 5, 1000000, 100);
}
void async_log()
{
    bit::GlobalLogBuilder builder("async", bit::level::logLevel::DEBUG, bit::LogBuilder::LogType::ASYNC, bit::AsyncLooper::LoopType::UN_SAFE);
    builder.buildLogFormat("%m");
    builder.buildSink<bit::FileSink>("async.log");
    builder.build();
    bench("async", 5, 1000000, 100);
}
int main()
{
    sync_log();
    return 0;
}